package Compression;

import core.FileItem;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

public class ZipFiles {

    
    //Thực hiện việc thêm 1 hoặc nhiều file vào file đã được nén
    public static void AppendFiles(File filezip, File[] fileappend) throws FileNotFoundException, IOException{
        ArrayList<File> files = new ArrayList<File>();
        for (File f: fileappend){
            addListFiles(files, f);
        }
        String tempPath = System.getProperty("java.io.tmpdir") + filezip.getName();
        File tempfile = new File(tempPath);
        boolean uz = ZipFiles.UnZip(filezip.getPath(), tempPath);
        FileItem.copyFiles(fileappend, tempfile);
        FileItem.deleteFile(filezip);
        ArrayList<File> tmp = new ArrayList<File>();
        for (File f: tempfile.listFiles()){
            addListFiles(tmp, f);
        }
        ZipFiles.ZipFile(tmp, filezip.getPath());
    }

    // Duyệt lấy file trong folder
    public static void addListFiles(ArrayList<File> alf, File folder){
        if (folder.isFile())
        {
            alf.add(folder);
            return;
        }
        
        for (File file : folder.listFiles()){
            if (file.isFile()){
                alf.add(file);
            }
            if (file.isDirectory()){
                addListFiles(alf,file);
            }
        }
    }

    //Thực hiện việc nén file,folder hoặc nhiều file,folder được chọn
    public static boolean ZipFile(ArrayList file, String des){
        try
        {
            ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(des));
            for (int i = 0; i < file.size(); i++)
            {
                File temp = (File) file.get(i);
                boolean kq = CompressFolder(zos, temp, "");
                if (kq == false)
                {
                    return kq;
                }
            }
            zos.close();
        }
        catch (Exception ex)
        {
            return false;
        }
        return true;
    }

    //Thực hiện việc nén file,folder hoặc nhiều file,folder được chọn
    public static boolean CompressFolder(ZipOutputStream zos, File file,String browse){
        try
        {
            if (file.isDirectory() == true)
            {
                File[] childs = file.listFiles();
                if (browse.equals("") == true)
                {
                    browse = file.getName();
                }
                else
                {
                    browse = browse + "\\" + file.getName();
                }
                for (int i = 0; i < childs.length; i++)
                {
                    if (childs[i].isDirectory() == true)
                    {
                        boolean kq = CompressFolder(zos, childs[i], browse);
                        if (kq == false)
                        {
                            return kq;
                        }
                    }
                    else
                    {
                        FileInputStream in = new FileInputStream(childs[i].getPath());
                        byte[] buf = new byte[in.available()];
                        zos.putNextEntry(new ZipEntry(browse + "\\" + childs[i].getName()));
                        int len;
                        while ((len = in.read(buf)) > 0)
                        {
                            zos.write(buf, 0, len);
                        }
                        zos.closeEntry();
                        in.close();
                    }
                }
            }
            else
            {
                FileInputStream in = new FileInputStream(file.getPath());
                byte[] buf = new byte[in.available()];
                zos.putNextEntry(new ZipEntry(file.getName()));
                int len;
                while ((len = in.read(buf)) > 0)
                {
                    zos.write(buf, 0, len);
                }
                zos.closeEntry();
                in.close();
            }
        }
        catch (Exception ex)
        {
            return false;
        }
        return true;
    }

    //Thực hiện việc giải nén
    public static boolean UnZip(String filezip, String fileunzip) throws FileNotFoundException, IOException{
        try {
            File file = new File(filezip);
            ZipInputStream zis = new ZipInputStream(new FileInputStream(file));
            ZipEntry entry;
            while ((entry = zis.getNextEntry()) != null) {
                int count = 0;
                byte[] data = new byte[1024];
                String[] temp = entry.getName().split("\\\\");
                String path = fileunzip + File.separator;
                for (int i = 0; i < temp.length - 1; i++) {
                    path = path + File.separator + temp[i];
                }
                new File(path).mkdirs();
                File fout = new File(path + File.separator + temp[temp.length - 1]);
                fout.createNewFile();
                FileOutputStream fos = new FileOutputStream(fout);
                while ((count = (zis.read(data, 0, 1024))) != -1) {
                    fos.write(data, 0, count);
                }
                fos.close();
            }
            zis.close();
            return true;
        }
        catch (FileNotFoundException ex) {
            return false;
        } catch (IOException ex) {
            return false;
        }
    }

    //Thực hiện việc hiển thị danh sách file hay thư mục trong file nén
    public static File ExploreZipFile(String sfilezip) throws FileNotFoundException, IOException{
        File filezip = new File(sfilezip);
        String tempPath = System.getProperty("java.io.tmpdir") + filezip.getName();
        boolean uz =ZipFiles.UnZip(sfilezip, tempPath);
        File file = new File(tempPath);
        return file;
    }
    
}
